// internal/parser/ast/expression.go
package ast

import (
	"strings"
)

// Identifier 表示标识符，如表名、列名等
type Identifier struct {
	Value string // 标识符的名称
}

// 实现Expression接口
func (i *Identifier) expressionNode()      {}
func (i *Identifier) TokenLiteral() string { return i.Value }
func (i *Identifier) String() string       { return i.Value }

// LiteralExpression 表示字面量表达式，如字符串、数字
type LiteralExpression struct {
	Value string    // 字面量的值
	Type  TokenType // 字面量类型（STRING或NUMBER）
}

// 实现Expression接口
func (l *LiteralExpression) expressionNode()      {}
func (l *LiteralExpression) TokenLiteral() string { return l.Value }
func (l *LiteralExpression) String() string {
	// 字符串字面量需要加引号
	if l.Type == STRING {
		return "'" + l.Value + "'"
	}
	return l.Value
}

// BinaryExpression 表示二元表达式，如比较和逻辑运算
type BinaryExpression struct {
	Left     Expression // 左操作数
	Operator TokenType  // 运算符（=, >, <, AND, OR等）
	Right    Expression // 右操作数
}

// 实现Expression接口
func (b *BinaryExpression) expressionNode()      {}
func (b *BinaryExpression) TokenLiteral() string { return b.Left.TokenLiteral() }
func (b *BinaryExpression) String() string {
	var out strings.Builder

	out.WriteString("(")
	out.WriteString(b.Left.String())

	switch b.Operator {
	case EQUAL:
		out.WriteString(" = ")
	case NOT_EQUAL:
		out.WriteString(" != ")
	case LESS:
		out.WriteString(" < ")
	case LESS_EQUAL:
		out.WriteString(" <= ")
	case GREATER:
		out.WriteString(" > ")
	case GREATER_EQUAL:
		out.WriteString(" >= ")
	case AND:
		out.WriteString(" AND ")
	case OR:
		out.WriteString(" OR ")
	}

	out.WriteString(b.Right.String())
	out.WriteString(")")

	return out.String()
}

// AsteriskExpression 表示SQL中的星号(*)，用于表示选择所有列
type AsteriskExpression struct{}

func (a *AsteriskExpression) expressionNode()      {}
func (a *AsteriskExpression) TokenLiteral() string { return "*" }
func (a *AsteriskExpression) String() string       { return "*" }

// SubqueryExpression 表示SQL中的子查询表达式
type SubqueryExpression struct {
	Query Statement // 嵌套的查询语句
}

// 实现Expression接口
func (s *SubqueryExpression) expressionNode()      {}
func (s *SubqueryExpression) TokenLiteral() string { return "SUBQUERY" }
func (s *SubqueryExpression) String() string {
	return "(" + s.Query.String() + ")"
}

// 将TokenType依赖性从lexer移入ast包
type TokenType int

// 定义表达式中用到的常量
const (
	STRING TokenType = iota
	NUMBER

	// 运算符
	EQUAL
	NOT_EQUAL
	LESS
	LESS_EQUAL
	GREATER
	GREATER_EQUAL
	AND
	OR
)
